home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
smaltalk
/
stv.lha
/
STV
/
st_v
/
compto.sit
/
CompareTool.app
Wrap
Text File
|
1992-11-07
|
20KB
|
485 lines
"
******************************************************************************
Application : CompareTool
Date : Nov 7, 1992
Time : 14:12:35
Introduction
============
This tool allows you to quickly compare the content of a file written
in chunk format (ie. ready to be filed in or a piece of a change.log)
with the current code in your image.
A menu named tools has only two options:
Load difference: Loads a file in chunk format to be analyzed
Load new method Makes a fileIn of the selected method into you
image (once this is done, the method is removed
since now, the two methods are identical).
The main window has two ListPane's in which contains the list of classes
and corresponding methods which have been found in the file and whioch are
different from the code in your current image (textual comparison only).
On the left a set of three button allows you to:
Difference: Show the differences
Old Show the code in your current image
New Show the code found in the file being analyzed.
Let me know if you find such tool useful.
(c) Didier BESSET 1992, all rights reserved.
CompuServe: 100020, 2313
Invoked By:
===========
The tool is started by
OmegaBaseTools new open
Then select the Load differences option of the Tool menu to load
a file.
Description
===========
Classes :
Methods :
#open defined in OmegaBaseTools.
#text defined in OmegaBaseTools.
#classes: defined in OmegaBaseTools.
#smalltalkClass defined in OmegaBaseTools.
#methods: defined in OmegaBaseTools.
#methods defined in OmegaBaseTools.
#classes defined in OmegaBaseTools.
#menu defined in OmegaBaseTools.
#displayMode: defined in OmegaBaseTools.
#compareMethods defined in OmegaBaseTools.
#accept:from: defined in OmegaBaseTools.
#acceptNewMethod defined in OmegaBaseTools.
#showDifferences:at:with:on: defined in OmegaBaseTools class.
#nextMethodFrom: defined in OmegaBaseTools class.
******************************************************************************
"!
"This application adds or changes methods of class OmegaBaseTools
The class should already exist in the system.
Object subclass: #OmegaBaseTools
instanceVariableNames:
'differences selectedClass selectedMethod display '
classVariableNames: ''
poolDictionaries: '' "!
!OmegaBaseTools methods !
open
"Open a new window to process differences"
| aTopPane listLineHeight ratio aPane |
differences := Dictionary new.
ratio := 3 / 10.
aTopPane := TopPane new
model: self;
label: 'OmegaBaseTools window';
minimumSize: 300 @ 200;
yourself.
aTopPane addSubpane:
(ListPane new
model: self;
name: #classes;
change: #classes:;
menu: #menu;
framingRatio:
(0 @ 0 extent: 1/3 @ ratio);
yourself).
aTopPane addSubpane:
(ListPane new
model: self;
name: #methods;
change: #methods:;
framingRatio:
(1/3 @ 0 extent: 1/3 @ ratio);
yourself).
aTopPane addSubpane:
(VerticalButtonPane new
model: self;
change: #displayMode:;
buttons: #(Differences Old New);
framingRatio:
(2/3 @ 0 extent: 1/3 @ ratio);
push: 1).
aTopPane addSubpane:
(TextPane new
model: self;
name: #text;
change: #accept:from:;
framingRatio: (0 @ ratio
corner: 1 @ 1);
yourself).
aTopPane dispatcher open.
aTopPane dispatcher scheduleWindow! !
!OmegaBaseTools methods !
text
"Display the method code or difference in the text pane"
| answer class |
selectedMethod isNil
ifTrue: [ ^''].
display = #Old
ifTrue: [ class := self smalltalkClass.
class notNil
ifTrue: [ answer := class sourceCodeAt: selectedMethod.
answer = selectedMethod
ifTrue: [ ^'***** New method!! *****']
ifFalse:[ ^answer].
]
ifFalse:[ ^'***** New class!! *****'].
].
answer := (differences at: selectedClass) at: selectedMethod.
display = #Differences
ifTrue: [ ^answer last]
ifFalse:[ ^answer first]! !
!OmegaBaseTools methods !
classes: aString
"Displays the methods for which differences were found
for class aString"
selectedClass := aString.
selectedMethod := nil.
self changed: #methods;
changed: #text.! !
!OmegaBaseTools methods !
smalltalkClass
"Answers the class corresponding to the selected class
or nil, if it is a new class"
| className class |
className := selectedClass asArrayOfSubstrings first asSymbol.
(Smalltalk includesKey: className)
ifTrue: [ ^Compiler evaluate: selectedClass]
ifFalse:[ ^nil].! !
!OmegaBaseTools methods !
methods: aString
"Answer the list of methods for the selected class"
selectedMethod := aString asSymbol.
self changed: #text.! !
!OmegaBaseTools methods !
methods
"Answer the list of methods for the selected class"
selectedClass isNil
ifTrue: [ ^Array new].
^(differences at: selectedClass) keys asSortedCollection! !
!OmegaBaseTools methods !
classes
"Anser all classes for which a difference was found"
^differences keys asSortedCollection! !
!OmegaBaseTools methods !
menu
"Private - Answer the main menu."
^ (Menu
labels: ('Load differences\Load new method')
breakLinesAtBackSlashes
lines: #(1)
selectors: #(compareMethods acceptNewMethod))
title: 'Tool'! !
!OmegaBaseTools methods !
displayMode: aSymbol
"Select the mode of display of the text pane"
| temporaries |
display := aSymbol.
self changed: #text! !
!OmegaBaseTools methods !
compareMethods
"Compare the methods of the selected file
with the one on the ClassHierarchy Browser"
| messageDelimiter aName method pos className inFile aChunk n m clName differ
methodDictionary |
differences := Dictionary new.
inFile := SFReply getFile.
inFile isNil
ifTrue: [ ^nil].
CursorManager read change.
[inFile atEnd]
whileFalse:[ aChunk := inFile nextChunk zapCrs.
n := aChunk indexOfString: ' methods'.
( n > 0)
ifTrue: [ aName := ((aChunk copyFrom: 1 to: (n - 1)) trimBlanks) .
m := true.
clName := aName asOrderedCollection.
'class' reverseDo:
[ :c | (m and: [c = clName last])
ifTrue: [ clName removeLast]
ifFalse:[ m := false].
].
m ifTrue: [ clName := (aName copyFrom: 1 to: (clName size)) trimBlanks]
ifFalse:[ clName := aName].
methodDictionary := differences at: aName
ifAbsent: [ differences at: aName
put: Dictionary new].
(Smalltalk includesKey: (clName asSymbol))
ifTrue: [ className := Compiler evaluate: (aName).].
[ pos := inFile position.
aChunk := inFile nextChunk.
inFile position: pos.
method := (self class nextMethodFrom: inFile) at: 1.
method isNil ]
whileFalse: [ className notNil
ifTrue: [
(aChunk = (className sourceCodeAt: method))
ifTrue: [ differ := false]
ifFalse: [ differ := WriteStream on: String new.
(self class showDifferences: className at: method with: aChunk on: differ)
ifTrue: [
methodDictionary at: method
put: (Array with: aChunk with: differ contents).
].
].
]
ifFalse:[
methodDictionary at: method
put: (Array with: aChunk with: nil).
].
]
].
].
inFile close.
CursorManager execute change.
(differences keys select: [ :k | (differences at: k) isEmpty])
do: [ :k | differences removeKey: k].
selectedClass := selectedMethod := nil.
self changed: #classes;
changed: #methods;
changed: #text.
CursorManager normal change.! !
!OmegaBaseTools methods !
accept: aString from: aDispatcher
"Accepts the changes for the selected class"
| aClass result |
aClass := self smalltalkClass.
aClass isNil
ifTrue: [ ^true].
CursorManager execute
showWhile: [ result := aClass compile: aString
notifying: aDispatcher].
result isNil ifTrue: [ ^ false ]
ifFalse: [
Smalltalk logSource: aString
forSelector: result key
inClass: aClass.
result key == selectedMethod ifFalse: [
selectedMethod := result key.
self changed: #selectors
with: #restoreSelected:
with: selectedMethod
].
^ true
]! !
!OmegaBaseTools methods !
acceptNewMethod
"Accepts the new method"
| aClass result aString classMethods |
selectedMethod isNil
ifTrue: [ Dialog message: 'No selected method!!'.
^nil].
aClass := self smalltalkClass.
aClass isNil
ifTrue: [ Dialog message: 'Class must be created first!!'.
^nil].
classMethods := differences at: selectedClass.
aString := (classMethods at: selectedMethod) first.
CursorManager execute
showWhile: [ result := aClass compile: aString].
result isNil ifTrue: [ ^ false ]
ifFalse: [
Smalltalk logSource: aString
forSelector: result key
inClass: aClass.
classMethods removeKey: selectedMethod.
classMethods isEmpty
ifTrue: [ differences removeKey: selectedClass.
selectedClass := nil.
self changed: #classes.
].
selectedMethod := nil.
self changed: #methods;
changed: #text.
^ true
]! !
!OmegaBaseTools class methods !
showDifferences: className at: method with: chunk2 on: aStream
"Prints the lines which differs between chunk1 and chunk2
on aStream.
Chunk1 is called the original code
Chunk2 is called the file code"
| chunk1 st1 st2 line1 line2 pos2 pos equal differ|
differ := false.
chunk1 := (className sourceCodeAt: method).
chunk1 = method
ifTrue: [ aStream cr; cr; nextPutAll: '***** Missing method ', method, ' for ', (className name).
^true].
st1 := ReadStream on: chunk1.
st2 := ReadStream on: chunk2.
pos2 := st2 position.
Transcript cr; nextPutAll: 'Checking method ', method, ' of ', (className name).
[st1 atEnd]
whileFalse: [ line1 := st1 nextLine zapGremlins.
line1 = ''
ifFalse:[
equal := false.
[st2 atEnd or: [equal] ]
whileFalse: [ line2 := st2 nextLine zapGremlins.
line2 = line1
ifTrue: [ equal := true].
].
equal
ifTrue: [ pos := st2 position.
st2 position: pos2.
[ line2 := st2 nextLine.
st2 position < pos]
whileTrue: [ line2 := line2 zapGremlins.
line2 isEmpty
ifFalse: [
differ
ifFalse: [ aStream cr; cr; nextPutAll: '***** Differences noted in ', ((className name), ', method ' , method).].
differ := true.
aStream cr; nextPutAll: '-------------> ',line2.
].
].
pos2 := pos.
]
ifFalse:[ st2 position: pos2.
differ
ifFalse: [ aStream cr; cr; nextPutAll: '***** Differences noted in ', ((className name), ', method ' , method).
differ := true.].
aStream cr; nextPutAll: line1.
].
].
].
[st2 atEnd]
whileFalse: [ line2 := st2 nextLine zapGremlins.
line2 isEmpty
ifFalse: [ differ
ifFalse: [ aStream cr; cr; nextPutAll: '***** Differences noted in ', ((className name), ', method ' , method).
differ := true.].
aStream cr; nextPutAll: '-------------> ',line2.
].
].
^differ! !
!OmegaBaseTools class methods !
nextMethodFrom: inFile
"Extract the next methods from Stream inFile"
| m n method selector aChunk|
[ inFile atEnd]
whileFalse:[
aChunk := inFile nextChunk.
method := (aChunk deepCopy) zapCrs.
method isEmpty
ifTrue: [ ^Array with: nil with: nil].
n := 1.
[ (method at: n) isSeparator]
whileTrue: [ n := n + 1].
m := n.
[ (m > method size)
or: [(method at: m) = $:
or: [(method at: m) isSeparator]]]
whileFalse: [ m := m + 1].
( m <= method size and: [(method at: m) = $:])
ifFalse: [ ^Array with: ((method copyFrom: n to: (m - 1)) asSymbol) with: aChunk].
selector := WriteStream on: String new.
[ (method at: m) = $: ]
whileTrue: [ selector nextPutAll: (method copyFrom: n to: m).
n := m + 1.
[ (method at: n) isSeparator]
whileTrue: [ n := n + 1].
[ (method at: n) isSeparator]
whileFalse: [ n := n + 1].
[ (method at: n) isSeparator]
whileTrue: [ n := n + 1].
m := n.
[(m > method size)
or: [(method at: m) = $:
or: [(method at: m) isSeparator]]]
whileFalse: [ m := m + 1].
m := m min: method size.
].
^Array with: ((selector contents) asSymbol) with: aChunk
].
^Array with: nil with: nil! !
"construct application"
((Smalltalk at: #Application ifAbsent: [])
isKindOf: Class) ifTrue: [
((Smalltalk at: #Application) for:'CompareTool')
addMethod: #showDifferences:at:with:on: forClass: OmegaBaseTools class;
addMethod: #nextMethodFrom: forClass: OmegaBaseTools class;
addMethod: #open forClass: OmegaBaseTools;
addMethod: #text forClass: OmegaBaseTools;
addMethod: #classes: forClass: OmegaBaseTools;
addMethod: #smalltalkClass forClass: OmegaBaseTools;
addMethod: #methods: forClass: OmegaBaseTools;
addMethod: #methods forClass: OmegaBaseTools;
addMethod: #classes forClass: OmegaBaseTools;
addMethod: #menu forClass: OmegaBaseTools;
addMethod: #displayMode: forClass: OmegaBaseTools;
addMethod: #compareMethods forClass: OmegaBaseTools;
addMethod: #accept:from: forClass: OmegaBaseTools;
addMethod: #acceptNewMethod forClass: OmegaBaseTools;
comments: 'This tool allows you to quickly compare the content of a file written
in chunk format (ie. ready to be filed in or a piece of a change.log)
with the current code in your image.
A menu named tools has only two options:
Load difference: Loads a file in chunk format to be analyzed
Load new method Makes a fileIn of the selected method into you
image (once this is done, the method is removed
since now, the two methods are identical).
The main window has two ListPane''s in which contains the list of classes
and corresponding methods which have been found in the file and whioch are
different from the code in your current image (textual comparison only).
On the left a set of three button allows you to:
Difference: Show the differences
Old Show the code in your current image
New Show the code found in the file being analyzed.
Let me know if you find such tool useful.
(c) Didier BESSET 1992, all rights reserved.
CompuServe: 100020, 2313
';
initCode: nil;
finalizeCode: nil;
startUpCode: 'The tool is started by
OmegaBaseTools new open
Then select the Load differences option of the Tool menu to load
a file.
']!